Consolidate the agent publish/share surface onto the canonical KA lifecycle (#1087)#1265
Conversation
… seal-retry recovery Addresses the PR #1265 review (otReviewAgent). - Removed the ensureContextGraphOnChain pre-call (+ unused import) from both publish CTAs (MemoryLayerView publishAssertions, ka.tsx VerifyOnDkgButton). The daemon /vm/publish route deliberately runs local preconditions FIRST and only registers the CG on the CG_NOT_REGISTERED retry path, rehydrating the STORED publishPolicy. The pre-call burned registration gas on a doomed publish and risked the #1085 default-policy (the UI register call sends no policy). The CTAs now call knowledgeAssetPublishWithSeal directly and let the daemon register at the right time. - Added 3 tests for the recovery contract: 409 PUBLISH_NOT_FULL_SHARE and VM_PUBLISH_PRECONDITION each -> wm/finalize{layer:'swm'} -> retry-once succeeds; SWM_SUBSET_NOT_SEALABLE -> typed throw, no retry loop. tsc clean; ui-api-pure 52/52. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…deleted publish route Addresses 2 PR #1265 review comments. - publish-get benchmark: the sync-leg KA name was benchmark-sync-<runId>-<iteration>, but runIteration runs for both warmup and measured phases with the same numeric iteration, so warmup-N and measured-N collided (name/idempotency-based create) and the GET validated the wrong marker. Name now includes the phase (benchmark-sync-<runId>-<warmup|measured>-<iteration>), mirroring the payload's own warmup-/measured- root+marker uniqueness. - context-graph-write-path-validation: added a negative test that POSTs the deleted /api/shared-memory/publish with a VALID CG and asserts 404 (unambiguous route-not-found) -- guards the route deletion against accidental reintroduction. cli tsc clean; the benchmark unique-roots + marker tests pass. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…te the api mocks Addresses 2 PR #1265 review comments. - /api/knowledge-assets/:name/vm/publish returns 207 when the KA minted on-chain but the CG binding failed (contextGraphError in the body; post() treats 207 as ok, so it rides through un-thrown). Typed contextGraphError on PublishResult + knowledgeAssetPublishWithSeal, and surfaced it: ka.tsx Verify CTA renders a warning ("binding incomplete") instead of a clean check; MemoryLayerView counts a `partial` tally, prefers a clean sample, and downgrades the result card to a warning when partial>0. Added a ui-api-pure test (207+contextGraphError resolves, no seal/retry). - Completed the full vi.mock('../src/ui/api.js') in the two component tests that load the components barrel (-> ka.tsx) with the new exports it imports (knowledgeAssetPublishWithSeal + the real SwmSubsetNotSealableError class), avoiding a missing-mock module-load failure. tsc clean; ui-api-pure 53/53; component-mock suites green. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
otReviewAgent
left a comment
There was a problem hiding this comment.
Operational Notice: Review Agent could not complete this review.
Synthesizer produced only invalid comment anchors.
✅ Ready for human review/merge — convergence reachedAll CI checks green (38 pass / 5 skip / 0 fail); every review thread resolved across 10 rounds with otReviewAgent, on top of 2 internal adversarial review passes before opening. What shipped (#1087)
Deferred (tracked in #1260, untouched here)
Product/agent surface has zero callers of the deleted route. Ready for human review + merge. |
otReviewAgent
left a comment
There was a problem hiding this comment.
Operational Notice: Review Agent could not complete this review.
Synthesizer produced only invalid comment anchors.
otReviewAgent
left a comment
There was a problem hiding this comment.
Operational Notice: Review Agent could not complete this review.
Synthesizer produced only invalid comment anchors.
otReviewAgent
left a comment
There was a problem hiding this comment.
Operational Notice: Review Agent could not complete this review.
Synthesizer produced only invalid comment anchors.
✅ Converged — all review rounds resolved, CI greenFollowing up on the summary above: review continued through several more rounds (all now resolved), including:
Final state: CI green (38 pass / 5 skip / 0 fail), 0 unresolved review threads, MERGEABLE. Ready for human review + merge. |
otReviewAgent
left a comment
There was a problem hiding this comment.
Operational Notice: Review Agent could not complete this review.
Synthesizer produced only invalid comment anchors.
otReviewAgent
left a comment
There was a problem hiding this comment.
Operational Notice: Review Agent could not complete this review.
Synthesizer produced only invalid comment anchors.
otReviewAgent
left a comment
There was a problem hiding this comment.
Operational Notice: Review Agent could not complete this review.
Synthesizer produced only invalid comment anchors.
otReviewAgent
left a comment
There was a problem hiding this comment.
Operational Notice: Review Agent could not complete this review.
Business logic reviewer failed: retry_exhausted
otReviewAgent
left a comment
There was a problem hiding this comment.
Operational Notice: Review Agent could not complete this review.
Business logic reviewer failed: retry_exhausted
501a05e to
b6fc66e
Compare
… seal-retry recovery Addresses the PR #1265 review (otReviewAgent). - Removed the ensureContextGraphOnChain pre-call (+ unused import) from both publish CTAs (MemoryLayerView publishAssertions, ka.tsx VerifyOnDkgButton). The daemon /vm/publish route deliberately runs local preconditions FIRST and only registers the CG on the CG_NOT_REGISTERED retry path, rehydrating the STORED publishPolicy. The pre-call burned registration gas on a doomed publish and risked the #1085 default-policy (the UI register call sends no policy). The CTAs now call knowledgeAssetPublishWithSeal directly and let the daemon register at the right time. - Added 3 tests for the recovery contract: 409 PUBLISH_NOT_FULL_SHARE and VM_PUBLISH_PRECONDITION each -> wm/finalize{layer:'swm'} -> retry-once succeeds; SWM_SUBSET_NOT_SEALABLE -> typed throw, no retry loop. tsc clean; ui-api-pure 52/52. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…deleted publish route Addresses 2 PR #1265 review comments. - publish-get benchmark: the sync-leg KA name was benchmark-sync-<runId>-<iteration>, but runIteration runs for both warmup and measured phases with the same numeric iteration, so warmup-N and measured-N collided (name/idempotency-based create) and the GET validated the wrong marker. Name now includes the phase (benchmark-sync-<runId>-<warmup|measured>-<iteration>), mirroring the payload's own warmup-/measured- root+marker uniqueness. - context-graph-write-path-validation: added a negative test that POSTs the deleted /api/shared-memory/publish with a VALID CG and asserts 404 (unambiguous route-not-found) -- guards the route deletion against accidental reintroduction. cli tsc clean; the benchmark unique-roots + marker tests pass. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…te the api mocks Addresses 2 PR #1265 review comments. - /api/knowledge-assets/:name/vm/publish returns 207 when the KA minted on-chain but the CG binding failed (contextGraphError in the body; post() treats 207 as ok, so it rides through un-thrown). Typed contextGraphError on PublishResult + knowledgeAssetPublishWithSeal, and surfaced it: ka.tsx Verify CTA renders a warning ("binding incomplete") instead of a clean check; MemoryLayerView counts a `partial` tally, prefers a clean sample, and downgrades the result card to a warning when partial>0. Added a ui-api-pure test (207+contextGraphError resolves, no seal/retry). - Completed the full vi.mock('../src/ui/api.js') in the two component tests that load the components barrel (-> ka.tsx) with the new exports it imports (knowledgeAssetPublishWithSeal + the real SwmSubsetNotSealableError class), avoiding a missing-mock module-load failure. tsc clean; ui-api-pure 53/53; component-mock suites green. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
otReviewAgent
left a comment
There was a problem hiding this comment.
Operational Notice: Review Agent could not complete this review.
Business logic reviewer failed: retry_exhausted
b6fc66e to
52cedc1
Compare
… seal-retry recovery Addresses the PR #1265 review (otReviewAgent). - Removed the ensureContextGraphOnChain pre-call (+ unused import) from both publish CTAs (MemoryLayerView publishAssertions, ka.tsx VerifyOnDkgButton). The daemon /vm/publish route deliberately runs local preconditions FIRST and only registers the CG on the CG_NOT_REGISTERED retry path, rehydrating the STORED publishPolicy. The pre-call burned registration gas on a doomed publish and risked the #1085 default-policy (the UI register call sends no policy). The CTAs now call knowledgeAssetPublishWithSeal directly and let the daemon register at the right time. - Added 3 tests for the recovery contract: 409 PUBLISH_NOT_FULL_SHARE and VM_PUBLISH_PRECONDITION each -> wm/finalize{layer:'swm'} -> retry-once succeeds; SWM_SUBSET_NOT_SEALABLE -> typed throw, no retry loop. tsc clean; ui-api-pure 52/52. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…deleted publish route Addresses 2 PR #1265 review comments. - publish-get benchmark: the sync-leg KA name was benchmark-sync-<runId>-<iteration>, but runIteration runs for both warmup and measured phases with the same numeric iteration, so warmup-N and measured-N collided (name/idempotency-based create) and the GET validated the wrong marker. Name now includes the phase (benchmark-sync-<runId>-<warmup|measured>-<iteration>), mirroring the payload's own warmup-/measured- root+marker uniqueness. - context-graph-write-path-validation: added a negative test that POSTs the deleted /api/shared-memory/publish with a VALID CG and asserts 404 (unambiguous route-not-found) -- guards the route deletion against accidental reintroduction. cli tsc clean; the benchmark unique-roots + marker tests pass. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…te the api mocks Addresses 2 PR #1265 review comments. - /api/knowledge-assets/:name/vm/publish returns 207 when the KA minted on-chain but the CG binding failed (contextGraphError in the body; post() treats 207 as ok, so it rides through un-thrown). Typed contextGraphError on PublishResult + knowledgeAssetPublishWithSeal, and surfaced it: ka.tsx Verify CTA renders a warning ("binding incomplete") instead of a clean check; MemoryLayerView counts a `partial` tally, prefers a clean sample, and downgrades the result card to a warning when partial>0. Added a ui-api-pure test (207+contextGraphError resolves, no seal/retry). - Completed the full vi.mock('../src/ui/api.js') in the two component tests that load the components barrel (-> ka.tsx) with the new exports it imports (knowledgeAssetPublishWithSeal + the real SwmSubsetNotSealableError class), avoiding a missing-mock module-load failure. tsc clean; ui-api-pure 53/53; component-mock suites green. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ecycle (#1087) Reconciled onto current main (incl. #1327 funded-wallet selection), Option 3: keep our complete node-ui migration + the novel daemon/tool cleanup; preserve #1327's funded-wallet mechanism untouched. - Remove the dkg_shared_memory_publish tool (MCP/OpenClaw/Hermes) + the /api/shared-memory/publish bridge route (+ the #1179 numeric-CG authz-bypass); a 404 guard pins the route as removed. - Add the D3 one-shot dkg_knowledge_asset_create({quads, alsoShareSwm}) across all three adapters (default-false, byte-parallel, stops at SWM). - Migrate ALL node-ui publish CTAs (MemoryLayerView, ka, entities, layer-widgets) off publishSharedMemory onto the canonical per-KA /vm/publish via the shared publishAssertionsToVm batch helper (seal-retry + 207 partial accounting). - Rewrite SKILL.md (x2) + tool descriptions to the canonical KA-lifecycle workflow. #1327's funded-wallet mechanism (chain/publisher/shared-assertion-helpers) is untouched; node-ui surfaces NO_FUNDED_PUBLISHER_WALLET natively via HttpError. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RF9DZa59J9cccmbpfEaSny
52cedc1 to
cd89640
Compare
…bridge route Three test groups carried in from main (added by #1327/#1329 AFTER this branch forked, so the original route deletion never saw them) still exercised the now- removed bridge route and failed in CI (8 tests): - delete daemon-swm-publish-transport.test.ts (#1329 bridge RPC-transport mapping; transport stays covered for /vm/publish by daemon-ka-transport + chain-rpc-transport-status) - remove the 'shared-memory publish authorship route matrix' block + its now-dead runSharedMemoryPublishRoute helper from context-graph-write-path-validation.test.ts (the positive 404-removed guard stays) - remove the obsolete assertionName-rejection test from knowledge-assets-route.test.ts Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RF9DZa59J9cccmbpfEaSny
…CTA test, doc nits) - 🔴 devnet /vm/publish callers threw on a tentative (non-OK 502) response BEFORE the existing retry: read the body first and retry the transient status:'tentative'/kaId:'0' outcome, throwing only on genuine hard failures (bootstrap.cjs, rich-scenario doPublish + edge publish, v10-stress doPublish). - 🟡 redistribute-memory.mjs: removed the unreachable SWM→VM publish section (disabled in #1087, pending #1260) + collapsed the redundant --skip-vm guard. - 🟡 drain-swm-duplicates.mjs: its sole purpose (the SWM drain) was removed in #1087, so hard-disable it — fail fast with a clear message + non-zero exit before any daemon scan/batch loop (old impl in git history). - 🟡 ka.tsx: added a VerifyOnDkgButton regression test — the entity publish CTA calls knowledgeAssetPublishWithSeal with the owning sourceAssertion + subGraphName, and disables for an entity with no named source assertion. - 🔵 api.ts JSDoc: publishAssertionsToVm collects failures into failures[] (not lastError). - 🔵 Hermes normalizer comment: narrowed the parity claim to classification + bracket stripping (literal escaping is Hermes-local _quote_literal). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RF9DZa59J9cccmbpfEaSny
Summary
create → write → seal → share → publish). This deletes the bypass/loose agent toolsdkg_publish(direct raw-quad mint),dkg_shared_memory_publish, anddkg_shareacross all three adapters (MCP, OpenClaw, Hermes), and re-points every internal caller onto the canonical per-KAPOST /api/knowledge-assets/:name/vm/publish.POST /api/shared-memory/publishentirely — both theassertionNameandselectionforks — and with it the Track C follow-up: numeric publishContextGraphId preflight bypass #1179 numeric-publishContextGraphIdbranch that trusted a caller-supplied on-chain CG id without an ownership check. The surviving publish routes enforce the ownership check.dkg_knowledge_asset_createwith optionalquads+alsoShareSwmso an agent cancreate → write → seal → sharein one call. It is default-false (sharing must be explicit), stops at SWM (never mints to VM), and is byte-parallel across all three adapters — so it cannot reintroduce a one-call bypass./vm/publish(named-only), with acatch 409 → seal-in-SWM → retry-oncesafety net; this also fixes a latent crash when a CG held ≥2 SWM roots.SKILL.mdfiles teach the single canonical flow and scrub every agent-facing loose-SWM/bridge reference;.cursor/rulesupdated; the skill-endpoint contract test is flipped to assert the bridge route is absent./api/shared-memory/write+/conditional-write) is kept — it is the staging buffer the source-worker bulk-ingest + async-LIFT pipeline depends on, and a live consumed channel (dkg_querySWM view, node-UI, gossip/sync). The SWM gossip/sync receive fabric (sync/host routes + handlers) is untouched. Three now-dead but publicly re-exported facade methods (DkgClient.publish,DkgPublisherExtension.publishVerifiableMemory/writeSharedMemory) that still call surviving routes are left for that follow-up.This change was implemented in waves and gated by a multi-angle adversarial review (plan-conformance, over-deletion, #1179 security, correctness, doc-truth, cross-adapter parity) before opening.
Related
publishContextGraphIdauthz-bypass branch (with the deleted bridge route)Files changed
packages/cli/src/daemon/routes/memory.tsPOST /api/shared-memory/publishroute (both forks) + the #1179 numeric-CG authz-bypass branch + the helpers it solely used; keep/write,/conditional-write,/memory/turn, and all sync/host routespackages/cli/src/api-client.tspublishFromFinalizedAssertiondelegates to/vm/publish; deleted thepublishFromSharedMemoryselection-fork shimpackages/cli/src/commands/shared-memory.ts,benchmark/publish-get/*/vm/publishflowpackages/mcp-dkg/src/tools/publish.ts(deleted),tools/assertions.ts,index.ts,client.tsdkg_publish/dkg_shared_memory_publish; extenddkg_knowledge_asset_create(D3); scrub the surviving publish descriptionpackages/adapter-openclaw/src/{tools/*,DkgNodePlugin.ts,dkg-client.ts,index.ts}dkg_publish/dkg_shared_memory_publish/dkg_share; extend create (D3); delete the 2 bridge-calling facade methodspackages/adapter-hermes/hermes-plugin/{__init__.py,client.py},src/types.ts,README.mddkg_memorypackages/core/src/publisher-extension.tspublishSharedMemoryfacade method + its transport member + dead request typepackages/node-ui/src/ui/{api.ts,views/MemoryLayerView.tsx,views/project/components/ka.tsx,hooks/useMemoryEntities.ts}/vm/publish(named-only) with a seal-retry chokepoint; remove dead loose-write codepackages/network-sim/src/{api.ts,components/ControlPanel.tsx,server/sim-engine.ts}/vm/publish; delete the loose-publish-by-selection helper + its buttonpackages/cli/skills/dkg-node/SKILL.md,dkg-importer/SKILL.md,.cursor/rules/dkg-annotate.mdcTest plan
dkg-core/dkg-storage/dkg-query, then run the impacted suites:pnpm -C packages/mcp-dkg test(227 pass; 2 known unicode inject-hook flakes)pnpm -C packages/adapter-openclaw test(1093 pass / 1 skip)PYTHON=python pnpm -C packages/adapter-hermes test(vitest 90) +pytest(113)pnpm -C packages/node-ui test(1273 pass; the better-sqlite3 native-binding suites are pre-existing env failures)pnpm -C packages/cli test(PR-touched suites green: auth, api-client, skill-endpoint)pnpm -C packages/core test(1084/1084)knowledge-assets-1116-share-errors,share-warning-parity, agente2e-memory-layers.SKILL.md; the D3 default-false / no-leak guard tests are green; cross-adapter parity holds.dkg_knowledge_asset_create({quads, alsoShareSwm:true})stops at SWM (no VM mint); publishing a named SWM assertion via/vm/publishworks; the node-UI publish button works for a named SWM root and is absent for un-named loose roots.Notes / known risks
dkg openclaw setupto pick up the newSKILL.md— the daemon serves/.well-known/skill.mdlive (MCP/Hermes/HTTP get it immediately), but OpenClaw copies the file into the agent workspace at setup./api/shared-memory/write+/conditional-write) — kept; the source-worker bulk-ingest + async-LIFT pipeline depends on it. Consolidating it onto the named-KA model is tracked in Consolidate daemon-level loose SWM writes onto the named-KA lifecycle (post agent-tooling cleanup) #1260.v10-core-flows,agent-provenance,rich-scenario,v10-stress) re-pointed to the named-KA flow, thepublish-loop.mjs+bootstrap.cjsscripts migrated, and the 3 ops.mjs(drain-swm-duplicates,redistribute-memory,seed-dkg-code-project) neutered (publish leg disabled + marked). The interconnected.shvalidation suite is deferred to Consolidate daemon-level loose SWM writes onto the named-KA lifecycle (post agent-tooling cleanup) #1260 and left untouched — the 10.shvalidators all publish through one shared bash helper (devnet_publish_swm_all_roots, 100% looseselection-publish) that ~9 more rfc38/rfc39 scenarios source; re-pointing it requires a per-scenario named-KA re-validation against a live devnet (mechanically gutting it would ship non-functional validators). Full scope documented in #1260. (A compat handler was rejected — it would resurrect the bridge route + the Track C follow-up: numeric publishContextGraphId preflight bypass #1179 authz-bypass.)entities.tsxpre-register — both sibling CTAs (entities.tsx,layer-widgets.tsx) now publish through the sharedknowledgeAssetPublishWithSealwrapper (seal-retry + 207 warning), andlayer-widgets' redundantensureContextGraphOnChainpre-register was removed. The one remaining deferred item isentities.tsx's pre-register, which is shared with the finalize/promote branch (removing it needs the promote-path analysis) — pre-existing, not introduced here.DkgClient.publish,DkgPublisherExtension.publishVerifiableMemory/writeSharedMemory) that still call surviving routes — left for a future library-API cleanup.